﻿using BZ.Core;
using BZ.Core.TaskExt;
using NDK.Motion.Sys;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace NDK.Motion.StationLogic
{
    /// <summary>
    /// 运行模式枚举
    /// </summary>
    public enum RunningModeEnum
    {
        /// <summary>
        /// 无选择模式
        /// </summary>
        NullMode,
        /// <summary>
        /// 生产模式
        /// </summary>
        ProductionMode,
        /// <summary>
        /// 工程师模式
        /// </summary>
        EngineeringMode,
        /// <summary>
        /// GRR模式
        /// </summary>
        GRRMode,
        /// <summary>
        /// 空跑模式
        /// </summary>
        EmptyMode,


    }
    //手自动枚举
    public enum AutoManualEnum
    {
        /// <summary>
        /// 手动模式
        /// </summary>
        Manual,
        /// <summary>
        /// 自动模式
        /// </summary>
        Auto,
    }
    public abstract class StationLogicAbstract : INotifyPropertyChanged
    {
        /// <summary>
        ///工站执行的线程
        /// </summary>
        private Thread processThread;

        /// <summary>
        /// 是否在动作中
        /// </summary>
        public bool IsInAction
        {
            get;
            private set;
        } = false;
        /// <summary>
        /// 机台Stoping后，工站是否停止
        /// </summary>
        public bool IsActionStoped
        {
            get;
            private set;
        } = false;


        /// <summary>
        /// 用于显示工站总CT
        /// </summary>
        public double stationCT = 0;
        /// <summary>
        /// 用于工站总CT记录
        /// </summary>
        public System.Diagnostics.Stopwatch swStationCT = new System.Diagnostics.Stopwatch();
        /// <summary>
        /// 用于工站内CT记录
        /// </summary>
        public System.Diagnostics.Stopwatch swStepTime = new System.Diagnostics.Stopwatch();
        /// <summary>
        /// 用于单步骤再分解CT记录
        /// </summary>
        public System.Diagnostics.Stopwatch swStepSplitTime = new System.Diagnostics.Stopwatch();
        public Dictionary<string, double> stepSplitTimeDic = new Dictionary<string, double>();
        /// <summary>
        /// 超时计时器
        /// </summary>
        public System.Diagnostics.Stopwatch swActionTimeout = new System.Diagnostics.Stopwatch();

        /// <summary>
        /// 当前运行GRR次数
        /// </summary>
        public int LocalGRRCount { get; set; }

        /// <summary>
        /// 属性变化事件
        /// </summary>
        public abstract event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 工站名
        /// </summary>
        public string Name
        {
            set; get;
        } = string.Empty;
        /// <summary>
        /// 工站描述
        /// </summary>
        public string Description
        {
            get; set;
        } = string.Empty;
        /// <summary>
        /// 工站线程
        /// </summary>
        protected Thread ProcessThread
        {
            get
            {
                return processThread;
            }
        }

        public StationLogicAbstract()
        {
            if (Name == string.Empty)
                Name = this.GetType().Name;
            if (Description == string.Empty)
                Description = this.GetType().FullName;
        }
        /// <summary>
        /// 工站线程的开启，并进行有料检测，工站初始化等
        /// </summary>
        public virtual void Init()
        {
            if (processThread == null || processThread.ThreadState == ThreadState.Stopped || processThread.ThreadState == ThreadState.Aborted)
            {
                string name = this.GetType().Name;
                processThread = TaskManager.Run(() =>
                {
                    Run();
                }, "StationThread--" + name);

                IsActionStoped = false;
                IsInAction = false;
                StationManager.StationList.Add(this);
            }
        }

        /// <summary>
        /// 停止工站线程
        /// </summary>
        public virtual void Stop()
        {
            #region 先等待线程自然停止，100ms超时后，强制停止线程
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Restart();
            while (IsActionStoped == false)
            {
                if (sw.ElapsedMilliseconds > 100)
                {
                    break;
                }
                Thread.Sleep(5);
            }
            #endregion
            if (processThread != null && processThread.IsAlive == true)
            {
                processThread.Abort();
            }
            TaskManager.Wait(processThread);
        }

        protected virtual void Run()
        {
            while (MachineStatusManager.CurrentMachineStatus != MachineStatus.Quit
                && MachineStatusManager.CurrentMachineStatus != MachineStatus.Stopping)
            {
                while (MachineStatusManager.CurrentMachineStatus == MachineStatus.Running)
                {
                    try
                    {
                        if (StationManager.MachineProductionMode == RunningModeEnum.ProductionMode)
                        {
                            IsInAction = true;
                            ActionProcess();
                            IsInAction = false;
                        }
                        else if (StationManager.MachineProductionMode == RunningModeEnum.EmptyMode)
                        {
                            IsInAction = true;
                            EmptyActionProcess();
                            IsInAction = false;
                        }
                        else if (StationManager.MachineProductionMode == RunningModeEnum.EngineeringMode)
                        {
                            IsInAction = true;
                            //EngineeringActionProcess();
                            IsInAction = false;
                        }
                        else if (StationManager.MachineProductionMode == RunningModeEnum.GRRMode)
                        {
                            IsInAction = true;
                            GRRActionProcess();
                            IsInAction = false;
                        }
                        else
                        {
                            AlarmPause("提示", "运行模式错误！", "请去登录页面选择对应的运行模式！", "");
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex is ThreadAbortException)
                        {
                            continue;
                        }
                        else if (ex is IOException)
                        {
                            AlarmPause("IO读写异常", ex.Message, "", "");
                            continue;
                        }
                        else if (ex is AxisException)
                        {
                            AlarmPause("轴异常", ex.Message, "", "");
                            continue;
                        }
                        AlarmPause("未知异常", ex.Message + ex.StackTrace, "请联系软件工程师", "");
                    }


                    Thread.Sleep(1);
                    Application.DoEvents();
                }
                Thread.Sleep(5);
            }
            IsActionStoped = true;
        }
        public string SNCode1 { set; get; }
        public bool 屏蔽1号治具 { set; get; }
        public bool 屏蔽2号治具 { set; get; }
        /// <summary>
        /// 机台报警暂停
        /// </summary>
        /// <param name="title">弹框报警的标题</param>
        /// <param name="exMsg">异常信息</param>
        /// <param name="exSolution">可能的异常原因,及解决方案</param>
        /// <param name="okOperationTip">点击OK的操作意义</param>
        /// <param name="cancelOperationTip">点击Cancel的操作意义</param>
        /// <returns>返回用户操作结果</returns>
        protected virtual DialogResult AlarmPause(string title, string excMsg, string exSolution, string okOperationTip, string cancelOperationTip)
        {
            MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;

            return MessageBox.Show(excMsg + Environment.NewLine
                + "【原因(解决方案)】" + exSolution + Environment.NewLine
                + "【确定】" + okOperationTip + Environment.NewLine
                + "【取消】" + cancelOperationTip, title, MessageBoxButtons.OKCancel);
        }
        protected virtual DialogResult AlarmPause(string title, string excMsg, string exSolution, string okOperationTip)
        {
            MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;

            return MessageBox.Show(excMsg + Environment.NewLine
               + "【原因(解决方案)】" + exSolution + Environment.NewLine
               + "【确定】" + okOperationTip + Environment.NewLine,
               title, MessageBoxButtons.OK);

        }
        protected virtual DialogResult AlarmPause(string title, string excMsg, string exSolution, string yesOperationTip, string noOperationTip, string cancelOperationTip)
        {
            MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;


            return MessageBox.Show(excMsg + Environment.NewLine
                + "【原因(解决方案)】" + exSolution + Environment.NewLine
                + "【是】" + yesOperationTip + Environment.NewLine
                + "【否】" + noOperationTip + Environment.NewLine
                + "【取消】" + cancelOperationTip,
                title, MessageBoxButtons.YesNoCancel);

        }
        /// <summary>
        /// GRR模式下的动作流程
        /// </summary>
        public abstract void GRRActionProcess();
        ///// <summary>
        ///// 工程师模式下的动作流程
        ///// </summary>
        //public abstract void EngineeringActionProcess();
        /// <summary>
        /// 空跑模式下的动作流程
        /// </summary>
        public abstract void EmptyActionProcess();
        /// <summary>
        /// 生产模式的下动作流程
        /// </summary>
        /// <param name="mode"></param>
        public abstract void ActionProcess();
    }
}
